// delay_us.c
#include "delay_us.h"

/**
 * @brief  初始化DWT计数器
 * @note   只在系统启动时调用一次，启用DWT计数器但不重置它
 */
void DWT_Init(void) {
    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // 启用 DWT
    DWT_CTRL |= CYCCNTENA;                         // 启用 CYCCNT
    // 不重置计数器，避免干扰其他任务
}

/**
 * @brief  微秒级延时函数
 * @param  us 延时时长（微秒）
 * @note   使用相对计时，不会影响其他任务
 */
void delay_us(uint32_t us)
{
    uint32_t start = DWT_CYCCNT;
    uint32_t cycles = us * (SystemCoreClock / 1000000);
    
    // 使用无符号运算处理溢出情况
    while ((uint32_t)(DWT_CYCCNT - start) < cycles);
}

/**
 * @brief  获取当前DWT计数值
 * @retval 当前计数值
 */
uint32_t DWT_GetTick(void)
{
    return DWT_CYCCNT;
}

/**
 * @brief  计算两个DWT计数值之间的时间差（微秒）
 * @param  start 开始计数值
 * @param  end 结束计数值
 * @retval 时间差（微秒）
 * @note   自动处理计数器溢出
 */
uint32_t DWT_GetDeltaUs(uint32_t start, uint32_t end)
{
    // 计算计数值差（自动处理溢出）
    uint32_t delta = end - start;
    // 转换为微秒
    return delta / (SystemCoreClock / 1000000);
}